package com.xiaotu.storage;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import com.xiaotu.common.util.Constants;
import com.xiaotu.common.util.DataRedisKeyUtils;
import com.xiaotu.common.util.DateUtils;
import com.xiaotu.common.util.MathUtil;
import com.xiaotu.storage.converter.AConverter;
import com.xiaotu.storage.converter.ConverterFactory;
import com.xiaotu.storage.model.CacheDataModel;

import net.sf.json.JSONObject;

/**
 * @类名 AHSetStorageProcessor
 * @日期 2017年2月22日
 * @作者 高海军
 * @功能 处理hset类型的缓存数据，转储成csv
 */
public abstract class AHSetStorageProcessor extends ACSVStorageProcessor
{
	
	protected static final String HKEYS = "HKEYS";
	
	protected static final int LAST_TARGET_CYCLE = 6;
	
	@Override
	public CacheDataModel setRedisData(CacheDataModel redisData, Date date)
	{
		if (redisData == null)
			redisData = new CacheDataModel();
		redisData.setDataList(null);
		String redisKey = this.getRedisKey(date);
		List<String> fieldList = redisData.getCacheData(HKEYS);
		if (fieldList == null)
		{
			Set<String> fieldSet = cacheHandler.hKeys(redisKey);
			if (fieldSet == null || fieldSet.isEmpty())
				return redisData;
			fieldList = new ArrayList<String>(fieldSet);
			redisData.putCacheData(HKEYS, fieldList);
		}
		
		int size = fieldList.size();
		if (size > 0)
		{
			long start = redisData.getStartIdx();
			long end = start + BATCH_SIZE;
			if (start >= size)
				return redisData;
			if (end > size)
				end = size;
			List<JSONObject> dataList = cacheHandler.hMGet(redisKey,
					JSONObject.class, fieldList.subList((int) start, (int) end)
							.toArray(new String[0]));
			redisData.setDataList(dataList);
			redisData.setStartIdx(end);
		}
		return redisData;
	}
	
	/**
	 * 获取上一次的爬取目标数据
	 * @param redisKey 换成key
	 * @param date 本次日期
	 * @param field 唯一标识
	 * @return 上次目标数据
	 */
	protected JSONObject getLastTarget(Constants.DataRedisKey redisKey,
			Date date, String field)
	{
		for (int i = 0; i < LAST_TARGET_CYCLE; i++)
		{
			date = DateUtils.getBeforeDay(date);
			JSONObject lastTarget = cacheHandler.hGet(
					DataRedisKeyUtils.getKey(redisKey, date), field,
					JSONObject.class);
			if (lastTarget != null)
				return lastTarget;
		}
		return null;
	}
	
	/**
	 * 设置天数据
	 * @param target 当前转储对象
	 * @param lastTarget 前一天的转储对象
	 * @param field 计算天数据的字段
	 * @param dayField 天数据保存时的字段名
	 * @param lastThrow 当前一天数据字段是否抛出转换异常
	 * @param targetThrow 当前天数据字段是否抛出转换异常
	 */
	protected boolean setDataDay(JSONObject target, JSONObject lastTarget,
			String field, String dayField, boolean lastThrow,
			boolean targetThrow)
	{
		if (lastTarget != null)
		{
			Object last = ConverterFactory.convert(lastTarget, field,
					AConverter.INTEGER_CONVERT, lastThrow);
			Object curr = ConverterFactory.convert(target, field,
					AConverter.INTEGER_CONVERT, targetThrow);
			
			if (last instanceof Number && curr instanceof Number)
			{
				target.put(dayField, (MathUtil.sub(curr, last)));
				return true;
			}
		}
		return false;
	}
}
